#
# Copyright (C) 2019 Niek Linnenbank
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

Import('build_env')

env = build_env.Clone()

for item in env['LINKUSER']:
    env['LINKFLAGS'].remove(item)

env.Append(LINKFLAGS = env['LINKKERN'])
env.Append(CPPFLAGS = '-D__KERNEL__')

env.UseLibraries(['liballoc', 'libstd', 'libarch', 'libipc', 'libfs', 'libexec'])
env.UseServers(['core', 'serial'])

env.TargetProgram('kernel.empty', [ Glob('*.cpp'),
                              Glob('#' + env['BUILDROOT'] + '/kernel/*.cpp'),
                              Glob('#' + env['BUILDROOT'] + '/kernel/API/*.cpp'),
                              Glob('#' + env['BUILDROOT'] + '/kernel/arm/*.cpp'),
                              Glob('#' + env['BUILDROOT'] + '/kernel/arm/*.S'),
                              '#' + env['BUILDROOT'] + '/server/serial/SerialDevice.o',
                              '#' + env['BUILDROOT'] + '/server/serial/NS16550.o'
                              ],
                   False)

#
# Place the stripped, compressed empty kernel in the rootfs for CoreServer
#
env.Strip('kernel.stripped', 'kernel.empty')
env.Lz4Compress('kernel.lz4', 'kernel.stripped')
env.TargetInstallAs('kernel.lz4', '${ROOTFS}/boot/kernel')

#
# Embed the boot.img in the kernel
#
env.Command('kernel', 'kernel.empty', env['OBJCOPY'] + ' ' +
            '--update-section .bootimg=' + env['BUILDROOT'] + '/boot.img ' +
            env['BUILDROOT'] + '/kernel/arm/' + env['SYSTEM'] + '/kernel.empty ' +
            env['BUILDROOT'] + '/kernel/arm/' + env['SYSTEM'] + '/kernel')
env.Depends('kernel', '#' + env['BUILDROOT'] + '/boot.img')

#
# Provide binary kernel image as input for U-Boot format image.
#
env.Command('kernel.img', 'kernel', env['OBJCOPY'] + ' -O binary ' +
            env['BUILDROOT'] + '/kernel/arm/' + env['SYSTEM'] + '/kernel ' +
            env['BUILDROOT'] + '/kernel/arm/' + env['SYSTEM'] + '/kernel.img')

#
# Provide kernel image with U-Boot header write to the SD card.
#
env.Command('kernel.ub', 'kernel.img', 'mkimage -T kernel -A arm -a 0x40100000 -O linux -C none -d ' +
            env['BUILDROOT'] + '/kernel/arm/' + env['SYSTEM'] + '/kernel.img ' +
            env['BUILDROOT'] + '/kernel/arm/' + env['SYSTEM'] + '/kernel.ub')

# First part of the Qemu command arguments
qemu_args = build_env['QEMUCMD'] + ' -kernel ' + build_env['BUILDROOT'] + \
            '/kernel/arm/' + build_env['SYSTEM'] + '/kernel ' + \
            '-chardev socket,id=charmonitor,path=monitor.dev,server,nowait -monitor chardev:charmonitor ' + \
            '-nographic'

#
# Qemu targets
#
env.Targets(qemu = qemu_args)

env.Targets(qemu_debug = qemu_args + ' -s -S')

env.Targets(qemu_mpi = qemu_args + ' -net nic,id=net0 -netdev user,id=hub0port0,hostfwd=udp:127.0.0.1:6661-:6660')

env.AutoTester(qemu_test = qemu_args)

env.AutoTesterLoop(qemu_loop = qemu_args)
